package com.bsg.upm.service;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.bsg.upm.check.AreaCheck;
import com.bsg.upm.check.CheckResult;
import com.bsg.upm.constant.DictTypeConstants;
import com.bsg.upm.constant.OperateDictConstants;
import com.bsg.upm.constant.OperateDictTypeConstants;
import com.bsg.upm.dto.AreaDto;
import com.bsg.upm.entity.AreaEntity;
import com.bsg.upm.entity.BackupStorageEntity;
import com.bsg.upm.entity.SiteEntity;
import com.bsg.upm.entity.UserEntity;
import com.bsg.upm.exception.APIException;
import com.bsg.upm.http.RespJson;
import com.bsg.upm.http.RespJsonFactory;
import com.bsg.upm.util.DateUtils;
import com.bsg.upm.util.PrimaryKeyUtils;

/**
 * 区域管理业务处理类
 * 
 * @author HCK
 *
 */
@Service
public class AreaService extends BaseService {

	@Resource
	private AreaCheck areaCheck;

	/**
	 * 区域查询
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson list(Map<String, Object> paramMap) throws APIException {
		try {
			// 结果集
			JSONArray results = new JSONArray();

			// 获取指定条件的区域
			List<AreaEntity> areas = areaDao.list(paramMap);

			for (AreaEntity area : areas) {
				// 构建区域展示对象
				AreaDto areaDto = buildShowDto(area, false);
				results.add(areaDto);
			}

			return RespJsonFactory.buildOK(results);
		} catch (Exception e) {
			logger.error("区域查询异常", e);
			throw new APIException("区域查询异常:" + e.getMessage());
		}
	}

	/**
	 * 区域详情
	 * 
	 * @param areaId
	 *            区域编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson get(String areaId) throws APIException {
		try {
			// 获取指定的区域
			AreaEntity area = areaDao.get(areaId);

			if (area == null) {
				return RespJsonFactory.build(HttpStatus.SC_GONE, "该区域不存在");
			}

			// 构建区域展示对象
			AreaDto areaDto = buildShowDto(area, true);

			return RespJsonFactory.buildOK(areaDto);
		} catch (Exception e) {
			logger.error("区域获取异常", e);
			throw new APIException("区域获取异常:" + e.getMessage());
		}
	}

	/**
	 * 区域新增
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson save(Map<String, Object> paramMap) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_ADD;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 区域新增检查
			CheckResult chkRS = areaCheck.checkSave(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			// 构建区域对象
			AreaEntity area = buildArea(paramMap);
			areaDao.save(area);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_AREA, operateAcion, area.getId(), area.getName(),
					area.getCreateDateTime());

			return RespJsonFactory.buildCreated();
		} catch (Exception e) {
			logger.error("区域" + operateAcionText + "异常", e);
			throw new APIException("区域" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 区域编辑
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson update(Map<String, Object> paramMap) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_UPDATE;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 区域编辑检查
			CheckResult chkRS = areaCheck.checkUpdate(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			// 构建区域对象
			AreaEntity area = buildAreaToUpdate(paramMap);
			areaDao.update(area);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_AREA, operateAcion, area.getId(), area.getName());

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			logger.error("区域" + operateAcionText + "异常", e);
			throw new APIException("区域" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 区域启用/停用
	 * 
	 * @param id
	 *            区域编码
	 * @param enable
	 *            是否启用
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson enable(String id, boolean enable) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_DISABLE;
		if (enable) {
			operateAcion = OperateDictConstants.ACTION_ENABLE;
		}
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 获取指定的区域
			AreaEntity area = areaDao.get(id);

			// 区域启停检查
			CheckResult chkRS = null;
			if (enable) {
				chkRS = areaCheck.checkEnable(area);
			} else {
				chkRS = areaCheck.checkDisable(area);
			}
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			// 设置启停状态
			area.setEnabled(enable);
			areaDao.updateEnabled(area);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_AREA, operateAcion, area.getId(), area.getName());

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			logger.error("区域" + operateAcionText + "异常", e);
			throw new APIException("区域" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 区域删除
	 * 
	 * @param id
	 *            区域编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson remove(String id) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_REMOVE;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 获取指定的区域
			AreaEntity area = areaDao.get(id);

			// 区域删除检查
			CheckResult chkRS = areaCheck.checkRemove(area);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			areaDao.remove(id);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_AREA, operateAcion, area.getId(), area.getName());

			return RespJsonFactory.buildNoContent();
		} catch (Exception e) {
			logger.error("区域" + operateAcionText + "异常", e);
			throw new APIException("区域" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 构建区域展示对象
	 * 
	 * @param area
	 *            区域对象
	 * @param showDetail
	 *            是否展示详情
	 * @return 区域展示对象
	 */
	private AreaDto buildShowDto(AreaEntity area, boolean showDetail) {
		AreaDto areaDto = new AreaDto();
		SiteEntity site = area.getSite();
		areaDto.setSiteId(site.getId());
		areaDto.setSiteName(site.getName());
		areaDto.setId(area.getId());
		areaDto.setName(area.getName());
		areaDto.setDescription(area.getDescription());
		areaDto.setEnabled(area.getEnabled());
		String enabledText = dictTypeCache.getTextFromCache(DictTypeConstants.STATUS_ENABLED,
				String.valueOf(area.getEnabled()));
		areaDto.setEnabledText(enabledText);
		areaDto.setCreateDateTime(DateUtils.dateTimeToString(area.getCreateDateTime()));
		areaDto.setCreateLoginUserName(area.getCreateUserLoginName());
		BackupStorageEntity backupStorage = area.getBackupStorage();
		areaDto.setBackupStorageId(backupStorage.getId());
		areaDto.setBackupStorageName(backupStorage.getName());
		return areaDto;
	}

	/**
	 * 构建区域对象
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return 区域对象
	 */
	private AreaEntity buildArea(Map<String, Object> paramMap) {
		AreaEntity area = new AreaEntity();
		area.setId(PrimaryKeyUtils.uniqueId());
		area.setName(StringUtils.trim((String) paramMap.get("name")));
		area.setEnabled(true);
		if (paramMap.containsKey("description")) {
			area.setDescription(StringUtils.trim((String) paramMap.get("description")));
		}
		area.setCreateDateTime(systemDao.getCurrentDateTime());
		UserEntity user = getUser();
		String username = user.getUsername();
		area.setCreateUserLoginName(username);
		SiteEntity site = new SiteEntity();
		site.setId((String) paramMap.get("site"));
		area.setSite(site);
		BackupStorageEntity backupStorage = new BackupStorageEntity();
		backupStorage.setId((String) paramMap.get("backupStorage"));
		area.setBackupStorage(backupStorage);
		return area;
	}

	/**
	 * 构建区域对象用于更新操作
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return 区域对象
	 */
	private AreaEntity buildAreaToUpdate(Map<String, Object> paramMap) {
		AreaEntity area = areaDao.get((String) paramMap.get("areaId"));
		if (paramMap.containsKey("name")) {
			area.setName(StringUtils.trim((String) paramMap.get("name")));
		}

		if (paramMap.containsKey("description")) {
			area.setDescription(StringUtils.trim((String) paramMap.get("description")));
		}

		if (paramMap.containsKey("backupStorage")) {
			BackupStorageEntity backupStorage = new BackupStorageEntity();
			backupStorage.setId((String) paramMap.get("backupStorage"));
			area.setBackupStorage(backupStorage);
		}
		return area;
	}

}
